/**
*****************************************************************************
 * @file pressuresensor.c
 * @brief 压力传感器设备函数(Keller)
 * @author luffy
 * @version V1.0.0
 * @date 2022/012/09
****************************************************************************
 */
#include "system.h"
#include "device_table.h"
#include "pressuresensor.h"
#include "FreeRTOS.h"
#include "task.h"
#include "drv_f4_gpio.h"
#include "drv_f4_usart.h"
#include "drv_f4_delay_168MHz.h"
//#include "A_shell.h"
//#include "A_log.h"
#include "func_DownMode.h"
#include "modbus_RTU_mast.h"
/* Private Struct ---------------------------------------------------------------*/
/* Private defines ---------------------------------------------------------------*/
/* Private enum ---------------------------------------------------------------*/
/* Private Variable ---------------------------------------------------------------*/
/* Private function prototypes -----------------------------------------------*/
static void PsComCallBack( uint8_t *data, uint32_t len);
static uint32_t PsCom_send_data(uint8_t *data, uint32_t len);
//static void pressuresensor_log_print(char *type, char *buffer, int len);
//static bool log_switch = false;
static uint8_t dev_addr = 1;     //
//Pointer
//Array

//UART5用做485（目前没有232外设），目前接两个传感器，通过地址识别
drv_gpio_t comB_wr = //485读写选择
{
	.PIN = "D3",
    .MODE = OUTPUT_DOWN,
    .INIT_LEVEL = LOW_LEVEL
};

drv_usart_t ps_comB = //压力传感器串口（RS485_A1）
{
	.Drv_Num = "UART5",
    .Tx_Pin = "C12",
    .Rx_Pin = "D2",
    .BaudRate = 9600,
    .WordLength = USART_WORDLENGTH_8BIT,
    .StopBits = USART_STOPBITS_1BIT,
    .Parity = USART_PARITY_NO,
    .Idle_CallBack = PsComCallBack,
    .Rx_Priority = 5,
};

func_DownMode_t ps_funB = //压力传感器下行设备管理
{
    .outTime = 20,    //超时时间
    .SendCnt = 0,       //重发次数
    .IdleDelay = 100,   //总线空闲时间
    .send_data = PsCom_send_data,
};

psensor_t pS1,pS3;

//static modbus_table_t PS_modbus_table[PS_modbus_table_num] =
//{
//	{0x0100, 2, MD_RO, TLV_FLOAT,   TLV_FLOAT,  1, &pBody.P_sensor1,  NULL},
////	{0x0102, 2, MD_RO, TLV_FLOAT,   TLV_FLOAT,  1, &pBody.T_sensor1,  NULL},
//};

//modbus_page_t pow_page = 
//{
//	.dev = "P_SENSOR_BODY",
//	.md_addr = 0x08,           //传感器MODBUS设备地址
//	.table = PS_modbus_table,
//	.table_num = PS_modbus_table_num,
//};

/*****************************************************************************
* @brief 串口接收回调函数
* ex:
* @par 
* None
* @retval 
*****************************************************************************/
static void PsComCallBack( uint8_t *data, uint32_t len)
{
	ps_funB.read_callback(&ps_funB, data, len);
}

/*****************************************************************************
* @brief 串口发送函数
* ex:
* @par 
* None
* @retval 
*****************************************************************************/
static uint32_t PsCom_send_data(uint8_t *data, uint32_t len)
{
    comB_wr.Write(&comB_wr, 1);
    ps_comB.Write(&ps_comB, data, len);
	vTaskDelay(pdMS_TO_TICKS(2));
    comB_wr.Write(&comB_wr, 0);
	return 0;
}

/*
 * @brief: 获取压力传感器处理的工作任务状态
 */
static DOWN_TASK_STATE meter_task_st(void *fun)
{
    if (fun == NULL)
        return Task_IsOver;
    else
        return Task_IsOk;
}

/*
 * @brief: 压力传感器任务接收数据处理
 */
static int32_t meter_task_recv(void *fun, uint8_t *pBuf, int32_t len)
{
    if (fun == NULL)
        return -1;

    if (pBuf == NULL)
    {
        pBody.status = pS1.status =  pS2.status =  pS3.status = 0;
		
        return 0;
    }
    else
        pBody.status = pS1.status =  pS2.status =  pS3.status = 1;  

    modbus_mast_decode(pBuf, len, dev_addr);
	
//    pressuresensor_log_print("RX:", (char *)pBuf, (int)len);
    return 0;
}

/*
 * @brief: 压力传感器任务发送数据处理
 */
static int32_t meter_task_send(void *fun, uint8_t *pBuf)
{
    int32_t res;
    if (fun == NULL || pBuf == NULL)
        return -1;
		
	//多个传感器循环读取
	dev_addr++;
	if(dev_addr >= P_sensor_num)
	{
		dev_addr = 1;
	}
	
//	res = read_AO(dev_addr, PS_modbus_table[0].addr,
//					PS_modbus_table[PS_modbus_table_num - 1].addr +
//						PS_modbus_table[PS_modbus_table_num - 1].num -
//						PS_modbus_table[0].addr,
//					pBuf);
    res = read_AO(dev_addr, PS_modbus_table[dev_addr][0].addr,
                        PS_modbus_table[dev_addr][PS_modbus_table_num - 1].addr +
                            PS_modbus_table[dev_addr][PS_modbus_table_num - 1].num -
                            PS_modbus_table[dev_addr][0].addr,
                        pBuf);
	
//    pressuresensor_log_print("TX:", (char *)pBuf, (int)res);
    return res;
}

/***********************************************************************************
 * @brief 压力传感器初始化		
 * ex:
 * @par
 * None
 * @retval void None
 **********************************************************************************/
void pressuresensorB_init(void)
{
    if (Drv_Gpio_Init(&comB_wr) < 0)
    {
        return;
    }

    if (Drv_Usart_Init(&ps_comB) < 0)
    {
        while (1); 
    }

    if (Func_DownMode_Init(&ps_funB) < 0)
    {
        while (1); 
    }

	//set_modbus_page(&ps_pageB, P_sensor_num);
	
    ps_funB.CommTaskApply(&ps_funB, ComType_Cycle, meter_task_st,
                          meter_task_send, meter_task_recv);
}

/***********************************************************************************
 * @brief 压力传感器轮训函数	
 * ex:
 * @par
 * None
 * @retval void None
 **********************************************************************************/
void pressuresensorB_handler(uint16_t timebase)
{
    ps_funB.DownMode_task(&ps_funB, timebase);
	
	//SoftDelay_ms(100);
	//将压力缓存提供接口可读多个值
}

#define USE_LOG 0
#if USE_LOG
/***********************************************************************************
 * @brief log打印函数	
 * ex:
 * @par
 * None
 * @retval void None
 **********************************************************************************/
static void pressuresensor_log_print(char *type, char *buffer, int len)
{
    if (log_switch == false || buffer == NULL || len == 0)
        return;

    LOG_HEX(type, 16, (unsigned char *)buffer, len);
}

static int pressuresensor_info(uint8_t argc, char **argv)
{
    if (argc >= 2)
    {
        if (!strcmp(argv[1], "log"))
        {
            if (argc >= 3)
            {
                if (!strcmp(argv[2], "open"))
                    log_switch = true;
                else if (!strcmp(argv[2], "close"))
                    log_switch = false;
            }
            else
            {
                Ashell_print("Please input pressuresensor <log (open, close)>.\r\n");
            }
        }
    }
    else
    {
        Ashell_print("Please input pressuresensor <log (open, close)>.\r\n");
    }
    return 1;
}
SHELL_EXPORT_CMD(SHELL_CMD_PERMISSION(0)|SHELL_CMD_TYPE(SHELL_TYPE_CMD_MAIN), pressuresensor, pressuresensor_info, pressuresensor operation);
#endif
